﻿using System;

namespace Hohlios.TMDBWrapper.DotNet.Model
{
    /// <summary>
    /// Model for passing data to browse function.
    /// </summary>
    /// <prop name="completeAction">Action to be completed after async call</prop>
    /// <prop name="orderBy">order the results 3 options rating, release, title</prop> 
    /// <prop name="order">direction the OrderBy 2 options asc, desc</prop> 
    /// <prop name="perPage">(Optional) number of results when paged</prop> 
    /// <prop name="page">(Optional) page of the results</prop> 
    /// <prop name="query">(Optional) movie title search</prop> 
    /// <prop name="minVotes">(Optional) minimum number of votes</prop> 
    /// <prop name="ratingMin">(Optional) minimum rating</prop> 
    /// <prop name="ratingMax">(Optional) maximum rating</prop> 
    /// <prop name="genres">(Optional) genres of results</prop> 
    /// <prop name="genresSelector">(Optional) and/or for multiple genres</prop> 
    /// <prop name="releaseMin">(Optional) minimum date range</prop> 
    /// <prop name="releaseMax">(Optional) maximum date range</prop> 
    /// <prop name="year">(Optional) year of release</prop> 
    /// <prop name="certifications">(Optional) MPAA certifications like PG, PG-13, etc</prop> 
    /// <prop name="companies">(Optional) studio of result</prop> 
    /// <prop name="countries">(Optional) country of result</prop> 
    public class MovieBrowseOptions
    {
        public OrderBy OrderBy { get; set; }
        public Order Order { get; set; }
        public int? PerPage { get; set; }
        public int? Page { get; set; }
        public string Query { get; set; } 
        public int? MinVotes { get; set; } 
        public int? RatingMin { get; set; } 
        public int? RatingMax { get; set; } 
        public string[] Genres { get; set; } 
        public string GenresSelector { get; set; }
        public DateTime? ReleaseMin { get; set; } 
        public DateTime? ReleaseMax { get; set; } 
        public string Year { get; set; } 
        public string[] Certifications { get; set; } 
        public string[] Companies { get; set; } 
        public string[] Countries { get; set; } 

        public MovieBrowseOptions()
        {
            OrderBy = OrderBy.release;
            Order = Order.desc;
        }

        public string GetFilters()
        {
            var filter = "";

            filter += GetFilter("order_by", OrderBy.ToString());
            filter += GetFilter("order", Order.ToString());
            filter += GetFilter("per_page", NullibleIntToString(PerPage));
            filter += GetFilter("page", NullibleIntToString(Page));
            filter += GetFilter("query", string.Join("+", Query.Split(' ')));
            filter += GetFilter("min_votes", NullibleIntToString(MinVotes));
            filter += GetFilter("rating_min", NullibleIntToString(RatingMin));
            filter += GetFilter("rating_max", NullibleIntToString(RatingMax));
            filter += GetFilter("genres", StringsJoin(Genres));
            filter += GetFilter("genres_selector", GenresSelector);
            filter += GetFilter("release_min", NullibleDateTimeToEpoch(ReleaseMin));
            filter += GetFilter("release_max", NullibleDateTimeToEpoch(ReleaseMax));
            filter += GetFilter("year", Year);
            filter += GetFilter("certifications", StringsJoin(Certifications));
            filter += GetFilter("companies", StringsJoin(Companies));
            filter += GetFilter("countries", StringsJoin(Countries));

            return filter;
        }

        private static string NullibleIntToString(int? value)
        {
            return value == null ? "" : value.ToString();
        }

        private static string StringsJoin(string[] value)
        {
            return value == null ? "" : string.Join(",", value);
        }

        private static string NullibleDateTimeToEpoch(DateTime? value)
        {
            return value == null ? "" : ((DateTime)value - new DateTime(1970, 1, 1)).TotalSeconds.ToString();
        }

        private static string GetFilter(string key, string value)
        {
            return string.IsNullOrEmpty(value) ? "" : string.Format("&{0}={1}", key, value);
        }
    }
}
